There
are multiple ways to look at types of services, and I've chosen to
consider the types of services based on the category of message they
accept.
RPC services
A Remote Procedure Call(RPC)
is a means of executing a function on a distant object. These remote
invocations are meant to appear as if they were happening locally and
typically following the request/response communication pattern. If
you've written DCOM or CORBA components before, then this is a familiar
concept. As SOAP gained traction, this was initially seen as just
another way to execute remote functions but in a more interoperable
way. However, this encourages a very point-to-point mentality.
RPC-style services follow the "Gang of Four" Command pattern
where objects (in our case, messages) correspond to the action you wish
to perform. In essence, you are sending a message that tells the remote
service what to do. For example, the payload of an RPC-style service
request meant to create a new customer entity would look like this:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<InsertNewCustomer xmlns="http://Seroter.BizTalkSOA.RPCExample">
<ID>010022</ID>
<Name>Amy Clark</Name>
<FacilityID>LHS2001</FacilityID>
</InsertNewCustomer>
</soap:Body>
</soap:Envelope>
While this type of command message may be acceptable for service requests that return a specific response (GetCustomerDetails or VerifyAddress),
it is not a good practice for messaging solutions. Why?
Architecturally, this is fairly tight coupling where the client
confidently knows exactly what the service is supposed to do with their
request and by the nature of the request, is demanding such behavior (DeleteCustomer).
That's fairly presumptive, no? If the client truly had the ability to
do this action themselves, they wouldn't need the service at all! In
truth, the caller is only capable of making polite requests to the
service where it remains the prerogative of the service to handle that
request as it sees fit. For example, a demand to AddNewCustomer
may not be a simple, synchronous event. The service may require human
validation of the customer entry, or even decide that it doesn't want
to add this new customer for reasons such as content duplication,
failure of business rules, or simply irrelevance to the system.
Where does RPC play in BizTalk Server solutions? The classic ASMX service generator had a choice of producing bare or wrapped services that dictated whether the service operation followed an RPC style or not. The default style, wrapped, would enclose the message payload with the name of the service operations.
The BizTalk WCF Service Publishing Wizard
offers no choice of messaging style. In fact, any WCF service generated
either from schemas or orchestrations will follow the document-style
outlined below. The name of the service operation is not part of the
SOAP payload. If you wish to promote an RPC style service and aren't
satisfied with the metadata generated by the BizTalk, you have the
option to author your own RPC-oriented WSDL and provide that as the
primary facade definition. Either way, the adapter is quite forgiving
with each format, as it can either strip out nodes from parent
elements, or conversely, add a wrapper to an inbound data object.
Document services
A
document-style service is one in which the payload represents an
encapsulated data structure devoid of any sort of instruction of what
to do with it. As you can imagine, this type of service operation is
much more coarse-grained and accepts plumper messages that are more
self-describing. The service has all it needs to perform its action and
doesn't rely on a stateful series of actions that provide context to
the operation. If we re-factored our above RPC-style payload to be more
document-centric, it might look like this:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<NewCustomer xmlns="http://Seroter.BiztalkSOA.RPCExample">
<ID>010022</ID>
<Name>Amy Clark</Name>
<FacilityID>LHS2001</FacilityID>
</NewCustomer>
</soap:Body>
</soap:Envelope>
Notice
that instead of having a functional directive as the focus of the
message payload, we are highlighting the data entity that is travelling
across the wire. Either the single recipient or the broad list of
subscribers can decide how they handle a NewCustomer and what they do with the data to fit their needs.
While
this type of service can be used for request/response operations, they
typically make lots of sense for scenarios where one application simply
needs to exchange data with another application. These services can
follow a one-way MEP when data is only being shared in a point-to-point
manner, or could also be a one-way MEP with a publish/subscribe flavor
where any interested party could have at the data.
Does
BizTalk Server support this document-centric service type? It certainly
does. As mentioned above, all BizTalk-generated WCF service endpoints
define a document-centric contract. We'll chat about this more in the
next chapter as we analyze the best ways to construct a schema for
service exposure. Specifically, we'll talk about how we should both
identify and shape our schemas to avoid functional presumption and
encourage reusable data entities.
Event services
Finally,
let's consider the step-brother of the document-style service: the
event service. For event services, when something of note occurs, the
service is invoked and a message explaining the event is distributed.
Unlike the document message, the event message typically contains a
limited amount of information. You're basically telling the service
that something important happened, but not sharing too much data or
instructing it as to what to do next.
In
these scenarios, it's quite possible that the service recipient will
have to call back to the source system to actually get the relevant
data set. Consider the event notification. When a new employee is added to the HR system, our service is called and the NewEmployeeEvent
message is transmitted. Let's say that BizTalk fans this message out to
all downstream systems that care about employee data. Our French
office's security badge application has a service exposed which accepts
the NewEmployeeEvent message and then
peeks to see which country the new employee is associated with. If that
country is France, then their service calls back to the source HR
system to retrieve the full employee profile. What exactly is in this
truncated event message if not the full document? Stay tuned for when
we dissect the event message and consider how best to use it. NewEmployee
In
the BizTalk sense, this sort of service is a very nice use of the
event-driven message bus and is a great fit for one-way or pub/sub
MEPs. Assuming that BizTalk accepts these event messages via its
inbound service adapters, what are the possible outcomes? Three options
are:
Fan the message out to downstream services that have their own event-handling logic.
Spawn a new orchestration workflow that performs event processing logic.
Generate additional event messages within the bus based on content in the original message.
While
event messages are typically asynchronous in nature, the life cycle of
event processing can actually exploit all three service types
identified in this chapter. In the sequence diagram below, I show how
an initial event message (Order Event) may give way to a command
request (GetOrderDetails) and a document-style response (OrderDetails).
The
thought of using BizTalk Server for this sort of event-style routing
may be counter to classic impressions of BizTalk as a simple
point-to-point broker. We've moved beyond that antiquated concept and
should consider BizTalk a serious option when architecting robust
service-oriented event processing systems.